package vn.edu.saigontech.ncms.service.impl;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;

import vn.edu.saigontech.ncms.model.info.Student;
import vn.edu.saigontech.ncms.model.info.StudentType;
import vn.edu.saigontech.ncms.model.info.Waiting;
import vn.edu.saigontech.ncms.model.program.Level;
import vn.edu.saigontech.ncms.model.program.Program;
import vn.edu.saigontech.ncms.model.user.User;
import vn.edu.saigontech.ncms.service.ProgramService;
import vn.edu.saigontech.ncms.service.WaitingService;
import vn.edu.saigontech.ncms.util.Checker;
import vn.edu.saigontech.ncms.util.DateUtil;

@SuppressWarnings("unchecked")
public class WaitingServiceImpl extends HibernateGenericService<Waiting, Long> implements WaitingService {
	
	public List<Waiting> find(Waiting waiting) {
		Criteria criteria = this.createCriteria();
		Criteria studentCriteria = criteria.createCriteria("student");
		if(Checker.isNotNull(waiting.getLevel().getProgram())) {
			Program program = ProgramService.INSTANCE.findById(waiting.getLevel().getProgram().getId());
			criteria.add(Restrictions.in("level", program.getLevels()));
		}
		if(Checker.isNotNull(waiting.getLevel().getId())) {
			criteria.add(Restrictions.eq("level", waiting.getLevel()));
		}
		if(Checker.isNotNull(waiting.getFromRegisteredDate()) && Checker.isNotNull(waiting.getToRegisteredDate())) {
			criteria.add(Restrictions.between("registeredDate", waiting.getFromRegisteredDate(), waiting.getToRegisteredDate()));
		} else {
			if(Checker.isNotNull(waiting.getFromRegisteredDate())) {
				criteria.add(Restrictions.ge("registeredDate", waiting.getFromRegisteredDate()));
			}
			if(Checker.isNotNull(waiting.getToRegisteredDate())) {
				criteria.add(Restrictions.le("registeredDate", waiting.getToRegisteredDate()));
			}
		}
		if(Checker.isNotNull(waiting.getStudent().getType())) {
			studentCriteria.add(Restrictions.eq("type", waiting.getStudent().getType()));
		}
		if(Checker.isNotNull(waiting.getStudent().getConsultant())) {
			studentCriteria.add(Restrictions.eq("consultant", waiting.getStudent().getConsultant()));
		}
		return criteria.list();
	}
	
	@Override
	public List<Waiting> findByDate(Date fromDate, Date toDate) {
		Criteria criteria = this.createCriteria();
		if(Checker.isNotNull(fromDate) && Checker.isNotNull(toDate)) {
			criteria.add(Restrictions.between("registeredDate", fromDate, toDate));
		}
		return criteria.list();
	}

	@Override
	public Waiting createBlankWaiting() {
		Waiting waiting = new Waiting();
		
		Program program = new Program();
		Level level = new Level();
		level.setProgram(program);
		
		Student student = new Student();
		student.setType(new StudentType());
		student.setConsultant(new User());
		student.setProgram(new Program());
		
		waiting.setStudent(student);
		waiting.setLevel(level);
		return waiting;
	}

	/* halnt */
	@Override
	public List<Waiting> findByDateNProgram(int month, int year, Long programId) {
		Date startDate = DateUtil.getStartDateOfMonth(month, year);
		Date endDate = DateUtil.getEndDateOfMonth(month, year);
		
		Criteria criteria = this.createCriteria();
		criteria.add(Restrictions.between("registeredDate", startDate, endDate));
		
		Criteria level = criteria.createCriteria("level");
		Criteria program = level.createCriteria("program");		
		program.add(Restrictions.eq("id", programId));
		return criteria.list();
	}
}